/**
 * Author:  LiShibin.
 * Date:    2016/9/9.
 * File：   .
 */

/**
 * 深拷贝
 * @param {Object} 被复制的对象
 * @param {Object} 目标对象,默认为空对象
 * @return {Object}}
 */
function clone(obj, target) {
  var target = target || {};
  for(var i in obj) {
    if(typeof obj[i] === 'object') {
      target[i] = (obj[i].constructor === Array) ? [] : {};
      clone(obj[i], target[i]);
    } else {
      target[i] = obj[i];
    }
  }
  return target;
}
/**
 * 部分复制，只对目标对象拥有的属性进行复制，且为浅复制
 * @param obj 被复制的对象
 * @param target 目标对象
 */
function partClone(obj, target){
  Object.keys(obj).forEach((value)=> {
    if (target.hasOwnProperty(value)) {
      target[value] = obj[value];
    }
  })
  return target;
}

/**
 * 判断对象是否为空对象
 * @param e 判断对象
 * @returns {boolean}
 */
function isEmptyObject(e) {
  // vue 框架给数组添加了一个$remove的方法，所以对数组单独判断
  if (e instanceof Array) {
    if (e.length > 0) {
      return false
    } else {
      return true
    }
  }
  for (var t in e) {
    return false
  }
  return true
}

/**
 * 触发点击事件
 * @param element
 */
function clickElement(element) {
  // console.log(typeof  element);
  if(typeof element == "string") {
    element = document.getElementById(element);
  }
  var e = document.createEvent("MouseEvents");
  e.initEvent("click", true, true);
  element.dispatchEvent(e);
  // console.log(element);
  //element.click();
}

/**
 * 压缩图片
 * @param file 图片文件
 * @param fileSize 图片文件的大小
 * @callBack 压缩完成后的回调函数，参数：(base64)
 */
function compress(file, callBack)
{
  var self = this;
  var img = new Image();
  //最大宽度
  var maxW = 640;
  //压缩比
  var compressRate = 0.6;


  img.onload = function() {
    var cvs = document.createElement('canvas');
    var ctx = cvs.getContext('2d');

    if(img.width > maxW) {
      img.height *= maxW / img.width;
      img.width = maxW;
    }
    cvs.width = img.width;
    cvs.height = img.height;
    ctx.clearRect(0, 0, cvs.width, cvs.height);
    ctx.drawImage(img, 0, 0, img.width, img.height);

    var dataUrl = cvs.toDataURL('image/jpeg', compressRate);
    if(typeof callBack == 'function') {
      callBack(dataUrl);
    }
  }

  img.src = file;
}
/**
 * 冷却，防止快速重复点击
 * @param element 要冷却的节点
 * @param coolingTime 冷却时间（ms），默认为1000(ms)
 */
function coolingElement(element,coolingTime){
  coolingTime=coolingTime||1000;
  if(typeof element == "string") {
    element = document.getElementById(element);
  }
  element.disabled=true;
  setTimeout(function(){
    element.disabled=false;
  },coolingTime);
}

/**
 * 锁定
 * @param element 要锁定的dom
 * @param timeOut 锁定时间，默认1秒
 * @return {boolean} 是否在锁定状态中
 */
function freeze(element, timeOut) {
  timeOut = timeOut || 1000
  if (typeof element === 'string') {
    element = document.getElementById(element)
  }
  let freezeFlag = element.getAttribute('freeze-flag') // 是否锁定中
  let freezeFlagCountdown = element.getAttribute('freeze-flag-countdown') // 是否已经开始倒计时解锁中
  console.log('freezeFlag', freezeFlag)
  if (freezeFlag) {
    if (!freezeFlagCountdown) {
      element.setAttribute('freeze-flag-countdown', 'true') // 开始倒计时
      setTimeout(() => { // 倒计时结束
        element.removeAttribute('freeze-flag-countdown')
        element.removeAttribute('freeze-flag')
      }, timeOut)
    }
    return true
  } else {
    element.setAttribute('freeze-flag', 'true')
    if (!freezeFlagCountdown) {
      element.setAttribute('freeze-flag-countdown', 'true') // 开始倒计时
      setTimeout(() => { // 倒计时结束
        element.removeAttribute('freeze-flag-countdown')
        element.removeAttribute('freeze-flag')
      }, timeOut)
    }
    return false
  }
}

/**
 * 初始化百度地图对象
 * @param key 百度密钥
 * @returns {Promise} 异步对象
 */
function initMap(key) {
  return new Promise((resolve, reject) => {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = 'http://api.map.baidu.com/getscript?v=2.0&ak=' + key +'&services=&t=' + (new Date).getTime()
    script.onload = (event) => {
      resolve(window.BMap, event)
    }
    script.onerror = (error) => {
      reject(error)
    }
    document.head.appendChild(script)
  });
}
/**
 * 直接获取定位对象
 * @returns {Promise}
 */
function getLocal() {
  return new Promise((resolve, reject) => {
    var mapDiv = document.createElement('div');
    initMap('tzAcIFZ5xCoRwm63NcBGfoVB').then(BMap => {
      var map = new BMap.Map(mapDiv);
      var getLocation = new BMap.Geolocation();
      var geocoder = new BMap.Geocoder();;
      getLocation.getCurrentPosition(function(cp) {
        geocoder.getLocation(cp.point, function(cl) {
          var options = cl.addressComponents;
          options.point = cl.point;
          resolve(options)
        });
      },function(e) {
        console.log("getCurrentPosition失败：");
        console.log(e);
      });
    }, e => {
      console.log("initMap失败：");
      console.log(e);
    })
  });
}
/**
 * 比较两个对象是否相等
 * @param x
 * @param y
 * @returns {boolean}
 */
function cmp (x, y) {
  // If both x and y are null or undefined and exactly the same
  if (x === y) {
    return true
  }
  // If they are not strictly equal, they both need to be Objects
  if (!(x instanceof Object) || !(y instanceof Object)) {
    return false
  }
  // They must have the exact same prototype chain,the closest we can do is
  // test the constructor.
  if (x.constructor !== y.constructor) {
    return false
  }
  function innerCmp (a, b) {
    for (let p in a) {
      // Inherited properties were tested using x.constructor === y.constructor
      if (a.hasOwnProperty(p)) {
        // Allows comparing x[ p ] and y[ p ] when set to undefined
        if (!b.hasOwnProperty(p)) {
          return false
        }
        // If they have the same strict value or identity then they are equal
        if (a[p] === b[p]) {
          continue
        }
        // Numbers, Strings, Functions, Booleans must be strictly equal
        if ((typeof (a[p]) !== 'object') || (a[p] === null && b[p]) || (a[p] && b[p] === null)) {
          return false
        }
        let tmptag = innerCmp(a[p], b[p])
        if (tmptag === false) return false
        continue
        // if (x[p] !== y[p]) return false
        // Objects and Arrays must be tested recursively
      }
    }
    for (let q in b) {
      // allows x[ p ] to be set to undefined
      if (b.hasOwnProperty(q) && !a.hasOwnProperty(q)) {
        return false
      }
    }
  }

  let tmpTag = true
  tmpTag = innerCmp(x, y)
  if (tmpTag === false) return false
  return true
}


export {clone,clickElement,compress,coolingElement,isEmptyObject,getLocal,initMap,partClone,freeze, cmp};
